package com.guardchina.framework.mybatis.datasource;

import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallFilter;
import com.guardchina.framework.mybatis.api.RoutingDataSourceStrategy;
import com.guardchina.framework.mybatis.aspect.RoutingDataSourceAspect;
import com.guardchina.framework.mybatis.impl.PollingDataSourceStrategy;
import com.guardchina.framework.mybatis.propeties.RoutingDataSourceProperties;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * 描述：多数据源配置类
 *
 * @author lwb
 * @date 2019/3/21 17:18
 */
@EnableConfigurationProperties(RoutingDataSourceProperties.class)
@Configuration
@Slf4j
@AllArgsConstructor
@ConditionalOnProperty(prefix = "spring.datasource", name = "multiple", havingValue = "true")
@EnableTransactionManagement(order = 2)
public class RoutingDataSourceConfiguration {

    private RoutingDataSourceProperties routingDataSourceProperties;


    @Bean
    @ConditionalOnMissingBean(com.guardchina.framework.mybatis.datasource.RoutingDataSourceProvider.class)
    public com.guardchina.framework.mybatis.datasource.RoutingDataSourceProvider routingDataSourceProvider(){
        return new com.guardchina.framework.mybatis.datasource.RoutingDataSourceProvider(routingDataSourceProperties);
    }

    @Bean
    @ConditionalOnMissingBean(RoutingDataSourceStrategy.class)
    public RoutingDataSourceStrategy routingDataSourceStrategy(){
        return new PollingDataSourceStrategy();
    }

    @Bean
    @ConditionalOnMissingBean(RoutingDataSource.class)
    public RoutingDataSource routingDataSource(RoutingDataSourceProvider routingDataSourceProvider, RoutingDataSourceStrategy routingDataSourceStrategy){

        return new RoutingDataSource(routingDataSourceProvider, routingDataSourceStrategy);
    }

    @Bean
    @ConditionalOnMissingBean(RoutingDataSourceAspect.class)
    public RoutingDataSourceAspect routingDataSourceAspect(){
        return new RoutingDataSourceAspect();
    }

    @Bean(name = "transactionManager")
    public DataSourceTransactionManager transactionManager(){
        return new DataSourceTransactionManager(routingDataSourceProvider().loadMasterDataSource());
    }

    @Bean
    public WallConfig wallConfig(){
        WallConfig wallConfig = new WallConfig();
        wallConfig.setMultiStatementAllow(true);
        return wallConfig;
    }

    @Bean
    public WallFilter wallFilter(){
        WallFilter wallFilter = new WallFilter();
        wallFilter.setConfig(wallConfig());
        return wallFilter;
    }


}
